// File: jmcomic-core/src/main/java/dev/jukomu/common/postman/impl/CurlCffiSessionPostman.java
package dev.jukomu.common.postman.impl;

import dev.jukomu.common.postman.AbstractSessionPostman;
import dev.jukomu.common.postman.Postman;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 对应Python的CurlCffiSessionPostman，在Java中，我们将使用OkHttp作为底层实现。
 * 'impersonate'参数将被忽略，因为OkHttp不直接支持浏览器指纹模拟。
 */
public class CurlCffiSessionPostman extends AbstractSessionPostman {

    public static String POSTMAN_KEY = "curl_cffi_session"; // 对应Python的postman_key

    /**
     * 构造函数。
     *
     * @param kwargs 初始化参数Map。
     */
    public CurlCffiSessionPostman(Map<String, Object> kwargs) {
        super(kwargs);
    }

    @Override
    protected OkHttpClient createSession(Map<String, Object> kwargs) {
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();

        // 处理timeout
        Number timeout = (Number) kwargs.get("timeout");
        if (timeout != null) {
            clientBuilder.connectTimeout(timeout.longValue(), TimeUnit.SECONDS)
                    .readTimeout(timeout.longValue(), TimeUnit.SECONDS)
                    .writeTimeout(timeout.longValue(), TimeUnit.SECONDS);
        }

        // 处理allow_redirects
        Boolean allowRedirects = (Boolean) kwargs.get("allow_redirects");
        if (allowRedirects != null) {
            clientBuilder.followRedirects(allowRedirects);
            clientBuilder.followSslRedirects(allowRedirects);
        }

        // 处理proxies (与OkHttpPostman相同逻辑)
        Map<String, String> proxies = (Map<String, String>) kwargs.get("proxies");
        if (proxies != null && !proxies.isEmpty()) {
            String socksAddress = proxies.get("socks");
            if (socksAddress != null && socksAddress.startsWith("socks://")) {
                String[] parts = socksAddress.substring("socks://".length()).split(":");
                if (parts.length == 2) {
                    clientBuilder.proxy(new java.net.Proxy(java.net.Proxy.Type.SOCKS, new java.net.InetSocketAddress(parts[0], Integer.parseInt(parts[1]))));
                }
            } else {
                String httpAddress = proxies.get("http");
                if (httpAddress != null && (httpAddress.startsWith("http://") || httpAddress.startsWith("https://"))) {
                    String cleanAddress = httpAddress.replaceFirst("^(http|https)://", "");
                    String[] parts = cleanAddress.split(":");
                    if (parts.length == 2) {
                        clientBuilder.proxy(new java.net.Proxy(java.net.Proxy.Type.HTTP, new java.net.InetSocketAddress(parts[0], Integer.parseInt(parts[1]))));
                    }
                }
            }
        }

        // 处理verify (SSL验证) (与OkHttpPostman相同逻辑)
        Boolean verify = (Boolean) kwargs.get("verify");
        if (verify != null && !verify) {
            clientBuilder.hostnameVerifier((hostname, session) -> true);
            try {
                TrustManager[] trustAllCerts = new TrustManager[]{
                        new X509TrustManager() {
                            @Override
                            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                            }

                            @Override
                            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                            }

                            @Override
                            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                                return new java.security.cert.X509Certificate[]{};
                            }
                        }
                };
                SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustAllCerts, new SecureRandom());
                clientBuilder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]);
            } catch (Exception e) {
                System.err.println("Failed to disable SSL verification: " + e.getMessage());
            }
        }

        // 处理cookies：OkHttp的CookieJar是Session的核心。
        Map<String, Object> initialCookiesMap = (Map<String, Object>) kwargs.get("cookies");
        if (initialCookiesMap != null && !initialCookiesMap.isEmpty()) {
            clientBuilder.cookieJar(new CookieJar() {
                private final List<Cookie> cookies = new ArrayList<>(); // 简单的内存Cookie存储

                {
                    // Convert initial cookies map to OkHttp Cookie objects
                    // This part needs more careful domain/path handling for real-world scenarios.
                    // For a basic implementation, we'll assume a dummy domain.
                    // A proper CookieJar would parse HttpUrl and build cookies more accurately.
                    for (Map.Entry<String, Object> entry : initialCookiesMap.entrySet()) {
                        cookies.add(new Cookie.Builder()
                                .name(entry.getKey())
                                .value(String.valueOf(entry.getValue()))
                                .domain("example.com") // Placeholder, should be the actual domain later
                                .build());
                    }
                }

                @Override
                public void saveFromResponse(HttpUrl url, List<Cookie> newCookies) {
                    // Add new cookies received from responses to our store
                    cookies.addAll(newCookies);
                }

                @Override
                public List<Cookie> loadForRequest(HttpUrl url) {
                    // Return cookies relevant to the request's URL (domain/path matching)
                    // For simplicity, return all for now. A real CookieJar filters.
                    return cookies;
                }
            });
        } else {
            clientBuilder.cookieJar(CookieJar.NO_COOKIES);
        }

        // 处理impersonate：对于OkHttp，impersonate参数会被忽略
        if (kwargs.containsKey("impersonate")) {
            System.err.println("Warning: 'impersonate' parameter is ignored by CurlCffiSessionPostman as it's specific to curl_cffi. This is a placeholder for a no-impersonation HTTP client.");
        }

        return clientBuilder.build();
    }

    @Override
    public Postman copy() {
        return new CurlCffiSessionPostman(new HashMap<>(metaData));
    }
}